package com.mytrip.aop;

import java.lang.reflect.Method;
import java.util.Date;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

import com.newheight.dao.BaseDao;
import com.newheight.dao.impl.IBatisDaoUtils;
import com.newheight.exception.BaseException;
import com.newheight.model.BackendAccessLog;
import com.newheight.model.BackendDataLog;
import com.newheight.model.BaseModel;
import com.newheight.model.McSiteProductPic;
import com.newheight.model.Picture;
import com.newheight.model.Product;
import com.newheight.model.ProductAttributeValue;
import com.newheight.model.ProductMerchant;
import com.newheight.model.ProductPriceRule;
import com.newheight.model.ProductSearchUpdate;
import com.newheight.model.ProductSupplier;
import com.newheight.service.log.BackendLogManager;
import com.newheight.service.log.ProductSearchUpdateManager;
import com.newheight.webapp.filter.CtxSessionBag;


@Aspect
public class BackendDataLogAspect extends BaseAspect {
	
	private BackendLogManager backendLogManager;

	private ProductSearchUpdateManager productSearchUpdateManager;
	
	public void setBackendLogManager(BackendLogManager backendLogManager) {
		this.backendLogManager = backendLogManager;
	}
	
	public void setProductSearchUpdateManager(ProductSearchUpdateManager productSearchUpdateManager) {
		this.productSearchUpdateManager = productSearchUpdateManager;
	}


	// ~ method
	// ==================================================================

	@Pointcut("(execution(* com.newheight.dao..*DaoImpl.save*(com.newheight.model.BaseModel)) "
			+ "|| execution(* com.newheight.dao..*DaoImpl.update*(com.newheight.model.BaseModel))) "
			+ "&& !within(com.newheight.dao.impl.BackendAccessLogDaoImpl) "
			+ "&& !within(com.newheight.dao.impl.BackendDataLogDaoImpl) "
			+ "&& !within(com.newheight.dao.impl.ProductSearchUpdateDaoImpl) "
			+ "&& !within(com.newheight.dao.impl.LoginFromBackendLogDaoImpl) "
			+ "&& !within(com.newheight.dao.impl.SendMessageDaoImpl) ")
	public void dataSavePt() {
	}

	@Around("dataSavePt() && target(dao) && args(model)")
	public Object dataSaveAccess(ProceedingJoinPoint pjp, BaseDao dao,
			BaseModel model) throws Throwable {

		BackendDataLog backendDataLog = new BackendDataLog();
		
		BackendAccessLog backendAccessLog = CtxSessionBag.getBackendAccessLog();
		if (backendAccessLog != null) {
			backendDataLog.setBackendAccessLog(backendAccessLog);
			backendDataLog.setOperatorId(backendAccessLog.getOperatorId());
			backendDataLog
					.setOperatorType(BackendAccessLog.OPERATOR_TYPE_BACK_OPERATOR);
			backendDataLog.setSessionNbr(backendAccessLog.getSessionNbr());
		} else {
			backendDataLog
					.setOperatorType(BackendAccessLog.OPERATOR_TYPE_BACK_SYSTEM);
		}

		backendDataLog.setModelName(model.getClass().getName());

		BaseModel orgModel = null;
		BaseModel aftModel = null;
		Long pk = (Long) IBatisDaoUtils.getPrimaryKeyValue(model);
		
		if (pk != null) {
			backendDataLog.setOperateFlag(BackendDataLog.OPERATE_FLAG_UPDATE);
			orgModel = dao.get(pk);
			backendDataLog.setModelPropertyBfrChg(orgModel.toString());
		} else {
			backendDataLog.setOperateFlag(BackendDataLog.OPERATE_FLAG_CREATE);
		}

		Object retObj = pjp.proceed();
		pk = (Long) IBatisDaoUtils.getPrimaryKeyValue(model);
		aftModel = dao.get(pk);

		backendDataLog.setModelPropertyAftChg(aftModel.toString());
		boolean isChanged = judgeModelChange(backendDataLog);
		
		if (isChanged){
			backendDataLog.setModelId(getPrimaryKeyValue(aftModel));
			backendLogManager.saveBackendDataLog(backendDataLog);
		}
		/**
		 * 名称，品牌,子系列
		 */
		 if (aftModel instanceof Product) {
	           Product oP=(Product)orgModel;
	           Product aP=(Product)aftModel;
	           if(oP!=null && aP !=null&&oP.getBrand()!=null&&aP.getBrand()!=null) {//编辑
	        	   if (!oP.getProductCname().equals(aP.getProductCname())
	                  ||!oP.getBrand().getId().equals(aP.getBrand().getId()) 
	                  || !oP.getCategory().getId().equals(aP.getCategory().getId())
	                  || aP.getProductType()==aP.PRODUCT_TYPE_VIRTUAL_SERIERS
	                //  || aP.getProductType()==aP.PRODUCT_TYPE_REAL_SERIERS 
	                  || oP.getProductType() != aP.getProductType()){
	        		   ProductSearchUpdate productSearchUpdate = new ProductSearchUpdate();
	        		   productSearchUpdate.setProductId(oP.getId());
		        	   productSearchUpdate.setUpdateStatus(0);
		        	   productSearchUpdate.setCreateTime(new Date());
		        	   productSearchUpdateManager.saveProductSearchUpdate(productSearchUpdate);
	        	   }
	           }
		 }
/*		 // 是否系列产品主产品
		else if (aftModel instanceof ProductSerial) {
				ProductSerial aPS = (ProductSerial) aftModel;
				ProductSearchUpdate pSUM = new ProductSearchUpdate();
				pSUM.setProductId(aPS.getProduct().getId());
				pSUM.setUpdateStatus(0);
				pSUM.setCreateTime(new Date());
				productSearchUpdateManager.saveProductSearchUpdate(pSUM);
			
		}*/
		 // 是否可销（批量处理）,可显（批量处理）
		 else if(aftModel instanceof ProductMerchant) {
			 if(aftModel!=null && orgModel !=null) {//编辑
			 ProductMerchant oPM=(ProductMerchant)orgModel;
			 ProductMerchant aPM=(ProductMerchant)aftModel;
			
	           if (!oPM.getCanSale().equals(aPM.getCanSale())
	                  || !oPM.getCanShow().equals(aPM.getCanShow())){
	        	   ProductSearchUpdate pSUM = new ProductSearchUpdate();
	        	   pSUM.setProductId(oPM.getProduct().getId());
	        	   pSUM.setUpdateStatus(0);
	        	   pSUM.setCreateTime(new Date());
	        	   productSearchUpdateManager.saveProductSearchUpdate(pSUM);
	           }
			 }
		 }
		 // 售价,是否促销
		else if (aftModel instanceof ProductPriceRule) {
			ProductPriceRule oPPR = (ProductPriceRule) orgModel;
			ProductPriceRule aPPR = (ProductPriceRule) aftModel;
			if (oPPR != null && aPPR != null) {
				if (oPPR.getProductNonMemberPrice() != aPPR.getProductNonMemberPrice()
						|| oPPR.getIsPromotion() != aPPR.getIsPromotion()) {
					ProductSearchUpdate pSUM = new ProductSearchUpdate();
					pSUM.setProductId(oPPR.getProduct().getId());
					pSUM.setUpdateStatus(0);
					pSUM.setCreateTime(new Date());
				    productSearchUpdateManager.saveProductSearchUpdate(pSUM);
				}
			}
		}
		 //修改进价
		else if(aftModel instanceof ProductSupplier) 
		{
			ProductSupplier oPS = (ProductSupplier) orgModel;
			ProductSupplier aPS = (ProductSupplier) aftModel;
			if (oPS != null && aPS != null) {
				if (oPS.getInPrice() != aPS.getInPrice()) {
					ProductSearchUpdate pSUM = new ProductSearchUpdate();
					pSUM.setProductId(oPS.getProduct().getId());
					pSUM.setUpdateStatus(0);
					pSUM.setCreateTime(new Date());
					productSearchUpdateManager.saveProductSearchUpdate(pSUM);
				}
			}
		}
		// 产品属性信息 导入
		else if (aftModel instanceof ProductAttributeValue) {
			ProductAttributeValue aPAV = (ProductAttributeValue) aftModel;
			if (aPAV != null) {
				ProductSearchUpdate pAV = new ProductSearchUpdate();
				pAV.setProductId(aPAV.getProduct().getId());
				pAV.setUpdateStatus(0);
				pAV.setCreateTime(new Date());
				productSearchUpdateManager.saveProductSearchUpdate(pAV);
			}
		}
		// 商品图片
		 else if (aftModel instanceof McSiteProductPic) {
			McSiteProductPic aMcSpp = (McSiteProductPic) aftModel;
			ProductSearchUpdate pSUm = new ProductSearchUpdate();
			pSUm.setProductId(aMcSpp.getProduct().getId());
			pSUm.setUpdateStatus(0);
			pSUm.setCreateTime(new Date());
			productSearchUpdateManager.saveProductSearchUpdate(pSUm);
		}
			
			 
		 
		return retObj;
	}
    private Long getPrimaryKeyValue(BaseModel o) {
        String getterMethod = "getId"; 
        try {
            Method getMethod = o.getClass().getMethod(getterMethod, (Class[]) null);
            Object rlt = getMethod.invoke(o, (Object[]) null);
            if(rlt instanceof Long) {
            	return (Long) rlt;
            }
        } catch (Exception e) {
        	log.error("::",e);
        }
        return null;
    }

	@Pointcut("execution(void com.newheight.dao..*DaoImpl.remove(*)) "
			+ "&& !within(com.newheight.dao.impl.BackendAccessLogDaoImpl) "
			+ "&& !within(com.newheight.dao.impl.BackendDataLogDaoImpl) "
			+ "&& !within(com.newheight.dao.impl.ProductSearchUpdateDaoImpl) "
			+ "&& !within(com.newheight.dao.impl.LoginFromBackendLogDaoImpl) ")
	public void dataRemovePt() {
	}

	
	@Around("dataRemovePt() && target(dao) && args(modelId)")
	public Object dataRemoveAccess(ProceedingJoinPoint pjp, BaseDao dao,
			Object modelId) throws Throwable {
		
		if (!(modelId instanceof Long)){
			return pjp.proceed();
		}
		
		BaseModel model = dao.get((Long) modelId);
		BackendDataLog backendDataLog = new BackendDataLog();
		
		BackendAccessLog backendAccessLog = CtxSessionBag.getBackendAccessLog();
		if (backendAccessLog != null) {
			backendDataLog.setBackendAccessLog(backendAccessLog);
			backendDataLog.setOperatorId(backendAccessLog.getOperatorId());
			backendDataLog
					.setOperatorType(BackendAccessLog.OPERATOR_TYPE_BACK_OPERATOR);
			backendDataLog.setSessionNbr(backendAccessLog.getSessionNbr());
		} else {
			backendDataLog
					.setOperatorType(BackendAccessLog.OPERATOR_TYPE_BACK_SYSTEM);
		}

		backendDataLog.setModelName(model.getClass().getName());
		backendDataLog.setOperateFlag(BackendDataLog.OPERATE_FLAG_DELETE);
		backendDataLog.setModelPropertyBfrChg(model.toString());

		BaseModel aftModel = null;
		Long pk = (Long) IBatisDaoUtils.getPrimaryKeyValue(model);
		Object retObj = pjp.proceed();
		try{
			aftModel = dao.get(pk);
		} catch(BaseException be){}

		if (aftModel != null){
			backendDataLog.setModelPropertyAftChg(aftModel.toString());
		}
		
		boolean isChanged = judgeModelChange(backendDataLog);		
		if (isChanged){
			backendLogManager.saveBackendDataLog(backendDataLog);
		} 
		
		/**
		 * 商品逻辑删除
		 */
		 if(model instanceof Product) {
			 Product oP=(Product)model;
			 Product aP=(Product)aftModel;
			 if (oP.getIsDeleted() != aP.getIsDeleted()){
				 ProductSearchUpdate psuIsdel = new ProductSearchUpdate();
				 psuIsdel.setProductId(aP.getId());
				 psuIsdel.setUpdateStatus(0);
				 psuIsdel.setCreateTime(new Date());
				 productSearchUpdateManager.saveProductSearchUpdate(psuIsdel);
	           }
		 }
		 //删除产品图片
		else if(model instanceof Picture) {
			Picture aP=(Picture)model;
			ProductSearchUpdate psuIsdel = new ProductSearchUpdate();
			psuIsdel.setProductId(aP.getResourceId());
			psuIsdel.setUpdateStatus(0);
			psuIsdel.setCreateTime(new Date());
			productSearchUpdateManager.saveProductSearchUpdate(psuIsdel);
		 }
		
		return retObj;

	}

	private boolean judgeModelChange(BackendDataLog backendDataLog) {
		boolean isChanged = false;
		if (backendDataLog.getModelPropertyBfrChg() == null 
				&& backendDataLog.getModelPropertyAftChg() != null){
			isChanged = true;
		} else if(backendDataLog.getModelPropertyBfrChg() != null 
				&& backendDataLog.getModelPropertyAftChg() == null){
			isChanged = true;
		} else if(backendDataLog.getModelPropertyBfrChg() != null 
				&& backendDataLog.getModelPropertyAftChg() != null
				&& !backendDataLog.getModelPropertyBfrChg().equals(backendDataLog.getModelPropertyAftChg())){
			isChanged = true;
		}
		return isChanged;
	}





}
